package com.lmscn.lms.api.controller;

import com.jfinal.aop.Before;
import com.jfinal.core.Controller;
import com.jfinal.plugin.activerecord.tx.Tx;
import com.lmscn.lms.api.model.*;
import com.lmscn.lms.api.util.BuildPaperUtil;
import com.lmscn.lms.api.util.DateUtil;
import com.lmscn.lms.api.util.JsonKit;
import com.lmscn.lms.api.util.KitUtil;
import com.lmscn.lms.commons.GlobalConst;
import com.lmscn.lms.domain.exam.ExamQuestionArea;
import com.lmscn.lms.domain.exam.ExamQuestionRule;
import com.lmscn.lms.domain.exam.ExamResultVo;
import com.lmscn.lms.domain.exam.QuestionVo;

import java.math.BigInteger;
import java.util.*;

import org.apache.commons.lang3.StringUtils;

/**
 * Created by Czl on 2015/9/11.
 */
public class MyExamController extends Controller {
    /**
     * 我的考试
     */
    public void myExam() {
        Long studentId = getParaToLong("studentId");
        Map<String, Object> dataMap = new HashMap<String, Object>();
        
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		Student student = Student.dao.findById(studentId);
		String studyGroup = student.getStr("study_group");
		Long cityId = student.getLong("city_id");
		int year = Integer.parseInt(DateUtil.getYear());
		List<Exam> list_exam = Exam.dao.getExamList(year, cityId, studyGroup);
		
		if (list_exam!=null && list_exam.size()>0) {
			Map<String, Object> map_2 = null;
			for (Exam exam : list_exam) {
				map_2 = new HashMap<String, Object>();
				map_2.put("exam", exam);
				studentExamResult(exam, studentId, map_2);
				list.add(map_2);
			}
			
			dataMap.put("myExam", list);
			dataMap.put("error_code", 0); 
			dataMap.put("msg", "请求成功!");
		} else {
			dataMap.put("error_code", 1); 
			dataMap.put("msg", "您没有参加我的考试");
		}
		renderJson(JsonKit.mapToJson(dataMap, 39));
    }
      
    
    public void studentExamResult(Exam exam, Long studentId, Map<String, Object> map_) {
    	String targetType = exam.getStr("target_type");
    	Long targetId = exam.getLong("target_id");
    	boolean hasMakeup = exam.getBoolean("has_makeup");
    	int examTimes = exam.getInt("times");
    	int limitScore = exam.getInt("pass_proportion");
    	int isFinish = 1;
    	Long maxScore = 0l;
    	int isMakeup = 1;         // 1补考   0非补考   -1所有
    	int makeup_times = 0;     // 补考次数
    	int leftMakeupTimes = 0;
    	int leftNormalTimes = 0;
    	/*** 查询补考 ***/
    	if (hasMakeup) {
    		maxScore = TestpaperResult.dao.getMaxScore(studentId, targetId, targetType, isFinish, isMakeup);
    		Long makeupTimes = TestpaperResult.dao.getTestpaperCount(studentId, targetId, targetType, isFinish, isMakeup);
    		makeup_times = makeupTimes==null ? 0 : makeupTimes.intValue();
    		leftMakeupTimes = examTimes - makeup_times;    // 剩余考试次数
    		// 判断是否有补考成绩
    		return ;
    	}
    	
    	/**** 查询正常考试 *****/
    	isMakeup = 0;
    	maxScore = TestpaperResult.dao.getMaxScore(studentId, targetId, targetType, isFinish, isMakeup);
    	Long normalTimes = TestpaperResult.dao.getTestpaperCount(studentId, targetId, targetType, isFinish, isMakeup);
    	int normal_times = normalTimes==null ? 0 : normalTimes.intValue();
    	leftNormalTimes = examTimes - normal_times;    // 剩余考试次数
    	
    	int max_score = maxScore==null ? 0 : maxScore.intValue();
    	map_.put("finalScore", max_score);                  // 最后成绩
    	map_.put("isPassedExam", max_score>=limitScore ? 1 : 0); // 是否通过考试
    	map_.put("normalExamTimes", normal_times);          // 考试次数
		map_.put("leftNormalExamTimes", leftNormalTimes);   // 剩余次数
		map_.put("hasMakeup", hasMakeup ? 1 : 0);           // 是否补考
		map_.put("makeupExamTimes", makeup_times);          // 补考总次数
		map_.put("leftMakeupExamTimes", leftMakeupTimes);   // 剩余补考次数
		map_.put("img_path", GlobalConst.COURSE_IMG);
    }
    
    
    /**
          * 考试说明
     */
    public void examInfo() {
    	
    	long examRuleId = getParaToLong("examRuleId");
        Map<String, Object> dataMap = new HashMap<String, Object>();
        ExamRule examRule = ExamRule.dao.getExamRule(examRuleId);
//		this.getRequest().setAttribute("canexam", this.getRequest().getParameter("canexam"));
        String ruleDesc = examRule.getStr("rule_desc");
        ruleDesc = ruleDesc.replaceAll("width:1080px;", "width:100%;");
        ruleDesc = ruleDesc.replaceAll("margin:0px auto;font-size:14px;", "margin:50px auto;padding-left:10px;padding-right:10px;font-size:28px;");
        ruleDesc = ruleDesc.replaceAll("line-height:23px;", "line-height:38px;");
        ruleDesc = ruleDesc.replaceAll("padding:8px 20px;text-align:right;", "text-align:right;");
        examRule.set("rule_desc", ruleDesc);
		dataMap.put("examRule", examRule);
		dataMap.put("error_code", 0); 
		dataMap.put("msg", "请求成功!");
        renderJson(JsonKit.mapToJson(dataMap, 39));
    }

    /**
	  * 进入我的考试
	  * 考试 /api/myExam/beginMyExam?
	  * http://120.77.0.245:9000/api/myExam/beginMyExam?studentId=70208&userType=ldgb&examId=1
     */
    @Before(Tx.class)
    public void beginMyExam() {
        Long studentId = getParaToLong("studentId");
        String userType = getPara("userType");
        Long examId = getParaToLong("examId");
//        Map<String, Object> dataMapList = new HashMap<String, Object>();
//        List<TestpaperResult> list = new ArrayList<TestpaperResult>();
//        Map<String, Object> finalMap = new HashMap<String, Object>();  //最终容器
        Map<String, Object> dataMap = new HashMap<String, Object>();
        canExam(studentId, userType, examId, dataMap);
        renderJson(JsonKit.mapToJson(dataMap, 39));
        
//        int answeredNum = 0;
//        TestpaperResult testpaperResult = null;
//        //通过班级ID查看是否存在班级考试
//        Exam exam = Exam.dao.getCourseExam(myexamId, "myexam");
//        if (exam == null) {
//            MyExamLearningSetting myExamLearningSetting = MyExamLearningSetting.dao.findByMyExamId(myexamId);
//            // 暂无考试 创建班级考试
//            Exam myexam_exam = getModel(Exam.class);
//            myexam_exam.saveMyExam(myExamLearningSetting, myexam_exam);
//            dataMapList = BuildPaperUtil.BuildExamPaper(myexam_exam, studentId);
//            list = TestpaperResult.dao.getTestpaperResult(studentId, myexam_exam.getLong("id"), "myexam", 0, -1, null);
//            if (list.size() > 0) {
//                testpaperResult = list.get(0);
//            }
//        } else {
//            if (BuildPaperUtil.isTwiceExam(studentId, exam.getLong("id"), "myexam")) {// 判断考试几次
//                //查看该学员是否存在未完成的试卷
//                list = TestpaperResult.dao.getTestpaperResult(studentId, exam.getLong("id"), "myexam", 0, -1, null);
//                if (list.size() > 0) {//如果大于0，说明存在未完成的答卷
//                    testpaperResult = list.get(0);
//                    //获取试卷都有哪些题目
//                    List questionList = TestpaperItem.dao.getQuestionList(testpaperResult.getLong("testpaper_id"));
//                    //获取学员已经答了哪些题。
//                    List studentQuestionList = TestpaperItemResult.dao.getQuestionList(testpaperResult.getLong("testpaper_id"), studentId);
//                    //把选项赋给题目
//                    List questions = new ArrayList();
//                    for (int i = 0; i < questionList.size(); i++) {
//                        Question question = (Question) questionList.get(i);
//                        List questionMetasList = QuestionMetas.dao.getQuestionMetas(Long.valueOf(question.getBigInteger("id").toString()));
//                        for (int j = 0; j < questionMetasList.size(); j++) {
//                            QuestionMetas questionMetas = (QuestionMetas) questionMetasList.get(j);
//                            question.set("item" + (j + 1) + "_id", questionMetas.get("options"));
//                        }
//                        questions.add(question);
//                    }
//                    Map<String, Object> questionsMap = new HashMap<String, Object>();
//                    questionsMap.put("question", questions);
//                    questionsMap.put("answered", studentQuestionList);
//                    dataMapList.put("questions", questionsMap);
//                    dataMap.put("answeredNum", studentQuestionList.size());
//                    answeredNum = studentQuestionList.size();
//                } else {//学员不存在未完成的答卷，则直接生成试卷
//                    dataMapList = BuildPaperUtil.BuildExamPaper(exam, studentId);
//                    list = TestpaperResult.dao.getTestpaperResult(studentId, exam.getLong("id"), "myexam", 0, -1);
//                    if (list.size() > 0) {
//                        testpaperResult = list.get(0);
//                    }
//                }
//                if (answeredNum == 0) {
//                    dataMap.put("answeredNum", 0);
//                }
//            } else {
//                dataMap.put("error_code", 1);
//                dataMap.put("msg", "考试已超过限制次数");
//                finalMap.put("testPaper", dataMap);
//                renderJson(JsonKit.mapToJson(finalMap, 39));
//            }
//        }
//        dataMap.put("limited_time", testpaperResult.getInt("limited_time"));
//        dataMap.put("used_time", testpaperResult.getInt("used_time"));
//        dataMap.put("testpaper_id", testpaperResult.getLong("testpaper_id"));
//        dataMap.put("questionAbout", dataMapList);
//        finalMap.put("testPaper", dataMap);
//        renderJson(JsonKit.mapToJson(finalMap, 39));
    }

    
    
    public boolean canExam(Long studentId, String userType, Long examId, Map<String, Object> dataMap) {
    	Student student = Student.dao.findById(studentId);
		String studyGroup = student.getStr("study_group");
		if (!userType.equals(studyGroup)) {
			dataMap.put("error_code", "1");
			dataMap.put("msg", "用户登录类型不匹配!");
			return false;
		}
		
    	int study_plan_year = Integer.parseInt(DateUtil.getYear());
    	List<Exam> list = Exam.dao.getJoinedYearStudyPlanExamList(
    			studentId, study_plan_year);
    	
    	String title = "";
    	boolean canJoin = true;
    	for (Exam exam : list) {
    		if(examId.longValue() != exam.getLong("id").longValue()){
    			title = exam.getStr("title");
				canJoin = false;
				break;
			}
    	}
    	
		if (!canJoin) {
			dataMap.put("error_code", 2); 
			dataMap.put("msg", "只可以参加一门考试，您已参加" + title); 
			return canJoin;
		}
		
		Long cityId = student.getLong("city_id");
		Exam exam = Exam.dao.getExam(examId);
		String cityIds = exam.getStr("city_ids");
		if (cityIds!=null && !"".equals(cityIds.trim())) {
			List<Long> ids = KitUtil.splitToLongList(cityIds);
			if (!ids.contains(cityId)) {
				dataMap.put("error_code", 3); 
				dataMap.put("msg", "非指定城市的学员");
				return false;
			}
		}
		
		Date now = new Date();
		boolean hasMakeup = exam.getBoolean("has_makeup");
		long startTime = exam.getTimestamp("start_time").getTime();
		long endTime = exam.getTimestamp("end_time").getTime();
		long nowSecond = now.getTime();
		int limitScore = exam.getInt("pass_proportion");   // 及格线
		int limitTimes = exam.getInt("times");             // 限考次数
		
		//考试尚未开始
		if (now.getTime() < startTime) {
			dataMap.put("error_code", 4); 
			dataMap.put("msg", "考试未开始");
			return false;
		}
	
		//考试已结束，并且没有补考
		if (endTime < nowSecond && !hasMakeup){
			dataMap.put("error_code", 5); 
			dataMap.put("msg", "考试已结束，且不能补考!");
			return false;
		}

		//已经通过了考试，不允许再次考试
		TestpaperResult result = TestpaperResult.dao
				.getFinishedTestpaperResult(studentId, 
				examId, GlobalConst.EXAM_TAEGET_TYPE, 1, -1);
		if (result!=null && result.getInt("score") >= limitScore) {
			dataMap.put("error_code", 6); 
			dataMap.put("msg", "通过后不能继续考试!");
			return false;
		}

		// 达到限考次数 且无补考
		Long examTimes = TestpaperResult.dao.getTestpaperCount(studentId, examId,
				GlobalConst.EXAM_TAEGET_TYPE, 1, -1);
		if (limitTimes>0 && examTimes>=limitTimes && !hasMakeup) {
			dataMap.put("error_code", 7); 
			dataMap.put("msg", "无考试机会且不存在补考!");
			return false;
		}
		
		List<TestpaperResult> unFinishExam = TestpaperResult.dao
				.getTestpaperResult(studentId, examId,
				GlobalConst.EXAM_TAEGET_TYPE, 0, -1, null);
		
		if (unFinishExam!=null && unFinishExam.size()>0) {
			TestpaperResult testPaperResult = unFinishExam.get(0);
			long testPaperId = testPaperResult.getLong("testpaper_id");
			Testpaper testPaper = Testpaper.dao.findById(testPaperId);
			Map<String, Object> data = new HashMap<String, Object>();
			data.put("testPaperResult", testPaperResult);
			data.put("img_path", GlobalConst.COURSE_IMG);
			historyPaper(exam, testPaper, data);
			dataMap.put("data", data); 
			dataMap.put("error_code", 0); 
			dataMap.put("msg", "请求成功!"); 
			
			return true;
		}
		
//		boolean isMakeup = false;
		Long examTimes_2 = TestpaperResult.dao.getTestpaperCount(studentId, examId,
				GlobalConst.EXAM_TAEGET_TYPE, -1, -1);
		if (examTimes_2>=limitTimes && hasMakeup) {
			Date makeupStartTime = exam.getTimestamp("makeup_start_time");
			Date makeupEndTime = exam.getTimestamp("makeup_end_time");
			Integer makeupTimes = exam.getInt("makeup_times");                     // 补考限考
			
			if (makeupStartTime!=null && nowSecond < makeupStartTime.getTime()) {  // 补考时间未到
				dataMap.put("error_code", 8); 
				dataMap.put("msg", "补考时间未到!");
				return false;
			}
			if (makeupEndTime!=null && makeupEndTime.getTime() < nowSecond) {      // 补考时间已经结束
				dataMap.put("error_code", 9);
				dataMap.put("msg", "补考已经结束!");
				return false;
			}
			
			Long makeupTime = TestpaperResult.dao.getTestpaperCount(studentId, examId,
					GlobalConst.EXAM_TAEGET_TYPE, -1, 1);
			if (makeupTimes!=null && makeupTimes>0 && makeupTime!=null && makeupTime>=makeupTimes) {      // 补考时间已经结束
				dataMap.put("error_code", 10);
				dataMap.put("msg", "无补考机会!");
				return false;
			}
		}
				
				
//		//有补考，补考期间，存在未完成的补考试卷--》跳转到试卷处
//		List<TestpaperResult> makeupTprs = examManager.getNotFinishedPaperResults(
//				loginStudent.getId(), exam.getId(), exam.getTargetType(),true);
//		if(exam.getHasMakeup() //有补考
//				&& exam.getMakeupStartTime().getTime() < now.getTime() && now.getTime() < exam.getMakeupEndTime().getTime()//补考期间
//				&& makeupTprs != null && makeupTprs.size() > 0 //存在未完成的补考试卷
//				){
//			this.testpaperResultId = makeupTprs.get(0).getId();
//			return SUCCESS;
//		}
				
//		// 有补考，补考期间，补考次数已到
//		int examMakeupTimes = testpaperResultManager.getTestpaperResultTimes(
//						exam.getTargetType(), exam.getId(), loginStudent.getId(),true);
//		if(exam.getHasMakeup() //有补考
//				&& exam.getMakeupStartTime().getTime() < now.getTime() && now.getTime() < exam.getMakeupEndTime().getTime()//补考期间
//				&& exam.getMakeupTimes() > 0 && examMakeupTimes >= exam.getMakeupTimes()  //补考次数已到
//				){
//			this.warn = "8";
//			return ERROR;
//		}
		
//		//判断当前要生成的试卷是不是补考试卷
//		boolean isMakeup = false;
//		if (hasMakeup==1) {
////				&& exam.getMakeupStartTime().getTime() < now.getTime()
////				&& now.getTime() < exam.getMakeupEndTime().getTime()//补考期间
//			isMakeup = true;
//		}
		Map<String, Object> data = buildPaper(exam, student, true);
		if (data!=null) {
			data.put("img_path", GlobalConst.COURSE_IMG);
			dataMap.put("data", data); 
			dataMap.put("error_code", 0); 
			dataMap.put("msg", "请求成功!"); 
			return true;
		}
		
		dataMap.put("error_code", 1); 
		dataMap.put("msg", "请求失败!"); 
		return false;
    }
    
    public void historyPaper(Exam exam, Testpaper testpaper, Map<String, Object> data) {
    	int randSingleNum = exam.getInt("rand_single_num");
		int randMultiNum = exam.getInt("rand_multi_num");
		int randChooseNum = exam.getInt("rand_choose_num");
		int randFillNum = exam.getInt("rand_fill_num");
		int score = randSingleNum * exam.getInt("rand_single_score") + randMultiNum
				* exam.getInt("rand_multi_score") + randFillNum
				* exam.getInt("rand_fill_score") + randChooseNum
				* exam.getInt("rand_choose_score");
		data.put("totalScore", score);
		
		//根据获取到的随机条件生成试卷题目
		List<Question> randSingleQuestionList = Question.dao.getQuestionByIds(testpaper.getStr("single_questions"));
		List<Question> randMultiQuestionList = Question.dao.getQuestionByIds(testpaper.getStr("multi_questions"));
		List<Question> randChooseQuestionList = Question.dao.getQuestionByIds(testpaper.getStr("determine_questions"));
		List<Question> randFillQuestionList = Question.dao.getQuestionByIds(testpaper.getStr("fill_blank_questions"));
		int itemNum = randSingleQuestionList.size() + randMultiQuestionList.size() + randChooseQuestionList.size() + randFillQuestionList.size();
		data.put("questionTotal", itemNum);
		
		// 先生成一份试卷
		List<QuestionVo> allQuestions = new ArrayList<QuestionVo>();
		allQuestions.addAll(questionMetas(randSingleQuestionList));
		allQuestions.addAll(questionMetas(randMultiQuestionList));
		allQuestions.addAll(questionMetas(randChooseQuestionList));
		allQuestions.addAll(questionMetas(randFillQuestionList));
		data.put("questions", allQuestions);
		data.put("exam", exam);
    }
    
    /**
	 * @Author:ZhangHaiwei
	 * @Description:创建试卷
	 * @param exam		考试信息
	 * @param student	学员信息
	 * @return
	 */
	public Map<String, Object> buildPaper(Exam exam, Student student, boolean isMakeup) {
		Map<String, Object> data = new HashMap<String, Object>();
		data.put("exam", exam);
		
		// 随机抽题组卷
		// 获取随机组卷的出题规则
		Long examId = exam.getLong("id");
		ExamQuestionArea examQuestionArea = new ExamQuestionArea();
		examQuestionArea.setExamId(examId);
		Long[] categoryIds = null;
		
		String randCateGoryId = exam.getStr("rand_categery_id");
		String questionArea = exam.getStr("question_area");
		
		
		//指定了抽题的题库
		if (randCateGoryId != null && !"".equals(randCateGoryId.trim())) {
			String[] categoryIdStrs = randCateGoryId.split(",");//题库
			categoryIds = new Long[categoryIdStrs.length];
			for (int i = 0; i<categoryIdStrs.length; i++) {
				categoryIds[i] = Long.valueOf(categoryIdStrs[i]);
			}
		} else {
			//没有指定参与抽题的题库，就默认是所有的题库
			List<QuestionCategory> cats = QuestionCategory.dao.getQuestionCategory();
			categoryIds = new Long[cats.size()];
			for(int i=0; i<cats.size(); i++){
				categoryIds[i] = cats.get(i).getLong("id");
			}
		}
		
		//如果没有指定抽题的范围
		if (questionArea == null || "".equals(questionArea.trim())) {
			examQuestionArea.setExamRules(null);
		} else {
			//如果指定了抽题范围
			examQuestionArea.setExamRules(ExamQuestionArea
					.getExamQuestionRuleByStr(questionArea.trim()));
		}
		
		int randSingleNum = exam.getInt("rand_single_num");
		int randMultiNum = exam.getInt("rand_multi_num");
		int randChooseNum = exam.getInt("rand_choose_num");
		int randFillNum = exam.getInt("rand_fill_num");
		int score = randSingleNum * exam.getInt("rand_single_score") + randMultiNum
				* exam.getInt("rand_multi_score") + randFillNum
				* exam.getInt("rand_fill_score") + randChooseNum
				* exam.getInt("rand_choose_score");
		data.put("totalScore", score);
		
		//根据获取到的随机条件生成试卷题目
		List<Question> randSingleQuestionList = getQuestionList(randSingleNum, "single_choice", categoryIds, examQuestionArea.getExamRules());
		List<Question> randMultiQuestionList = getQuestionList(randMultiNum, "multi_choice", categoryIds, examQuestionArea.getExamRules());
		List<Question> randChooseQuestionList = getQuestionList(randChooseNum, "determine_choose", categoryIds, examQuestionArea.getExamRules());
		List<Question> randFillQuestionList = getQuestionList(randFillNum, "fill_blank", categoryIds, examQuestionArea.getExamRules());
		int itemNum = randSingleQuestionList.size() + randMultiQuestionList.size() + randChooseQuestionList.size() + randFillQuestionList.size();
		data.put("questionTotal", itemNum);
		
		// 先生成一份试卷
		List<QuestionVo> allQuestions = new ArrayList<QuestionVo>();
		allQuestions.addAll(questionMetas(randSingleQuestionList));
		allQuestions.addAll(questionMetas(randMultiQuestionList));
		allQuestions.addAll(questionMetas(randChooseQuestionList));
		allQuestions.addAll(questionMetas(randFillQuestionList));
		data.put("questions", allQuestions);
		
//		Testpaper.dao.saveTestPaper(exam, allQuestions, studentId);
		
		String studentName = student.getStr("name");
		Long userId = student.getLong("user_id");
		Long studentId = student.getLong("id");
		String examTitle = exam.getStr("title");
		
		Testpaper testpaper = new Testpaper();// name,created_userid;created_time;target_id,target_type;
		testpaper.set("name", examTitle + "-" + studentName + "-" + System.currentTimeMillis());
		testpaper.set("limited_time", exam.getInt("limited_time"));
		testpaper.set("pattern", "3");
		testpaper.set("target_id", examId);
		testpaper.set("target_type", exam.getStr("target_type"));
		testpaper.set("choice_missscore", 0);
		testpaper.set("status", 0);
		testpaper.set("score", score);
		testpaper.set("item_count", exam.getInt("item_count"));
		testpaper.set("created_userid", userId);
		testpaper.set("created_time", new Date());
		testpaper.set("single_questions", getQuestionIds(randSingleQuestionList));
		testpaper.set("multi_questions", getQuestionIds(randMultiQuestionList));
		testpaper.set("determine_questions", getQuestionIds(randChooseQuestionList));
		testpaper.set("fill_blank_questions", getQuestionIds(randFillQuestionList));
		testpaper.set("single_question_num", randSingleQuestionList.size());
		testpaper.set("multi_question_num", randMultiQuestionList.size());
		testpaper.set("determine_question_num", randChooseQuestionList.size());
		testpaper.set("fill_blank_question_num", randFillQuestionList.size());
		testpaper.set("single_question_score", exam.getInt("rand_single_score"));
		testpaper.set("multi_question_score", exam.getInt("rand_multi_score"));
		testpaper.set("determine_question_score", exam.getInt("rand_choose_score"));
		testpaper.set("fill_blank_question_score", exam.getInt("rand_fill_score"));
		testpaper.set("student_id", studentId);
		testpaper.set("credit", 0);
		testpaper.set("reginfo_id", 0L);
		testpaper.remove("id").save();
		
		data.put("testpaper", testpaper);
		// 学员答卷记录表
		TestpaperResult testpaperResult = new TestpaperResult();
		testpaperResult.set("status", "doing");
        testpaperResult.set("testpaper_id", testpaper.getLong("id"));
        testpaperResult.set("student_id", studentId);
        testpaperResult.set("score", 0);
        testpaperResult.set("right_count", 0);
        testpaperResult.set("limited_time", exam.getInt("limited_time")*60);  // 考试时间限制（秒）
        testpaperResult.set("target_type", exam.getStr("target_type"));
        testpaperResult.set("target_times", 0);
        testpaperResult.set("target_id", exam.getLong("id"));
        testpaperResult.set("begin_time", new Date());
		Long targetTimes = testpaperResult.getTestpaperCount(studentId, examId,
				GlobalConst.EXAM_TAEGET_TYPE, -1, -1);
		int targetTimes_ = targetTimes==null ? 1 : targetTimes.intValue()+1; 
		testpaperResult.set("target_times", targetTimes_);
		testpaperResult.set("left_seconds", exam.getInt("limited_time") * 60);//考试剩余时间
		testpaperResult.set("last_save_time", testpaperResult.getDate("begin_time"));//最近一次保存时间
		testpaperResult.set("is_count_durative", exam.getBoolean("is_count_durative") ? 1 : 0);//是否持续性倒计时
		testpaperResult.set("is_makeup", isMakeup);
        testpaperResult.remove("id").save();
		
        data.put("testpaperResult", testpaperResult);
		return data;
	}
    
	public List<QuestionVo> questionMetas(List<Question> questionList) {
		List<QuestionVo> list = new ArrayList<QuestionVo>();
		if (questionList==null || questionList.size()==0) {
			return list;
		}
		
		QuestionVo vo = null;
		for (Question entity : questionList) {
			vo = new QuestionVo();
			BigInteger questionId = entity.getBigInteger("id");
			vo.setId(questionId.longValue());
			vo.setType(entity.getStr("type"));
			vo.setTitle(entity.getStr("title"));
			vo.setScore(entity.getLong("score").intValue());
			vo.setAnswer(entity.getStr("answer"));
			vo.setAnalysis(entity.getStr("analysis"));
			vo.setDifficulty(entity.getStr("difficulty"));
			String rightItem = entity.getStr("right_items");
			if (rightItem!=null && !"".equals(rightItem.trim())) {
				vo.setMetasId(Arrays.asList(rightItem.split(",")));
			}
			vo.setMetas(QuestionMetas.dao.getQuestionMetas(questionId.longValue()));
			list.add(vo);
		}
		
		return list;
	}
	
	
	/**
	 * 根据questionList获取questionId拼接的字符串
	 * @param questionList
	 * @return
	 */
	public String getQuestionIds(List<Question> questionList){
		if(questionList == null || questionList.size() == 0){
			return "";
		}
		StringBuffer sb = new StringBuffer();
		for (int i=0;i<questionList.size();i++) {
			sb.append(questionList.get(i).getBigInteger("id")+"");
			if (i < questionList.size() -1) {
				sb.append(",");
			}
		}
		return sb.toString();
	}
	
	
	/**
	 * @Author:ZhangHaiwei
	 * @Description:获取单选题
	 * @param singleChoiceTotal		要抽取的单选题的总数
	 * @param catrgoryIds				要抽取的题库
	 * @param examQuestionRules		指定抽取单选题数目的题库设置
	 * @return
	 */
	public List<Question> getQuestionList(int choiceTotal, String choiceType,
			Long [] categoryIds, Map<Long, ExamQuestionRule> examQuestionRules){
		List<Question> qlist = new ArrayList<Question>();
		if(choiceTotal <= 0){
			return qlist;
		}
		List<Long> catlist = new ArrayList<Long>(Arrays.asList(categoryIds));
		//从指定的题库中获取指定数目的单选题
		for(Long categoryId:categoryIds) {
			//要获取的题目数
			Integer choiceNum = 0;
			//任何题库都没有指定题目数量
			if(examQuestionRules == null){
				break;
			}
			//当前题库没有指定题目适量
			ExamQuestionRule rule = examQuestionRules.get(categoryId);
			if(rule == null){
				continue;
			}
			
			if("single_choice".equals(choiceType)){
				//当前题库没有指定单选题的数量
				if(rule.getSingleChoiceNum() == null || rule.getSingleChoiceNum() <= 0){
					continue;
				}
				choiceNum = rule.getSingleChoiceNum();
			}else if("multi_choice".equals(choiceType)){
				//当前题库没有指定多选题的数量
				if(rule.getMultiChoiceNum() == null || rule.getMultiChoiceNum() <= 0){
					continue;
				}
				choiceNum = rule.getMultiChoiceNum();
			}else if("determine_choose".equals(choiceType)){
				//当前题库没有指定选择题的数量
				if(rule.getDetermineChooseNum() == null || rule.getDetermineChooseNum() <= 0){
					continue;
				}
				choiceNum = rule.getDetermineChooseNum();
			} else if("fill_blank".equals(choiceType)) {
				//当前题库没有指定填空题的数量
				if(rule.getFillBlankNum() == null || rule.getFillBlankNum() <= 0){
					continue;
				}
				choiceNum = rule.getFillBlankNum();
			} else {
				return qlist;
			}
			
			if(choiceNum > 0){
				//删除当前题库
				catlist.remove(categoryId);
				//获取题目
				qlist.addAll(Question.dao.getQuestions(choiceType, choiceNum, categoryId+""));
			}
		}
		//找到了全部题，则返回
		if(choiceTotal <= qlist.size()){
			return qlist;
		}
		//剩余题目从剩余题库中选取
		qlist.addAll( Question.dao.getQuestions( choiceType,
				choiceTotal - qlist.size(),
				StringUtils.join(catlist.toArray(), ",") ) );
  		return qlist;
	}
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    /**
     * 进入我的考试
     * 练习
     */
    @Before(Tx.class)
    public void beginMyExamTest() {
        Long studentId = getParaToLong("studentId");
        Long myexamId = getParaToLong("myexamId");
        Map<String, Object> finalMap = new HashMap<String, Object>();//最终容器
        Map<String, Object> dataMapList = new HashMap<String, Object>();
        int answeredNum = 0;
        TestpaperResult testpaperResult = null;
        List<TestpaperResult> list = new ArrayList<TestpaperResult>();
        Map<String, Object> dataMap = new HashMap<String, Object>();
        //通过班级ID查看是否存在班级考试
        Test test = Test.dao.getTest(myexamId, "myexamtest");
        if (test == null) {
            MyExamLearningSetting myExamLearningSetting = MyExamLearningSetting.dao.findByMyExamId(myexamId);
            // 暂无考试 创建班级练习
            Test myexam_test = getModel(Test.class);
            myexam_test.saveMyTest(myExamLearningSetting, myexam_test);
            dataMapList = BuildPaperUtil.BuildTestPaper(myexam_test, studentId);
            list = TestpaperResult.dao.getTestpaperResult(studentId, myexam_test.getLong("id"), "myexamtest", 0, -1, null);
            if (list.size() > 0) {
                testpaperResult = list.get(0);
            }
        } else {
            //查看该学员是否存在未完成的试卷
            list = TestpaperResult.dao.getTestpaperResult(studentId, test.getLong("id"), "myexamtest", 0, -1, null);
            if (list.size() > 0) {//如果大于0，说明存在未完成的答卷
                testpaperResult = list.get(0);
                //获取试卷都有哪些题目
                List questionList = TestpaperItem.dao.getQuestionList(testpaperResult.getLong("testpaper_id"));
                //获取学员已经答了哪些题。
                List studentQuestionList = TestpaperItemResult.dao.getQuestionList(testpaperResult.getLong("testpaper_id"), studentId);
                //把选项赋给题目
                List questions = new ArrayList();
                for (int i = 0; i < questionList.size(); i++) {
                    Question question = (Question) questionList.get(i);
                    List questionMetasList = QuestionMetas.dao.getQuestionMetas(Long.valueOf(question.getBigInteger("id").toString()));
                    for (int j = 0; j < questionMetasList.size(); j++) {
                        QuestionMetas questionMetas = (QuestionMetas) questionMetasList.get(j);
                        question.set("item" + (j + 1) + "_id", questionMetas.get("options"));
                    }
                    questions.add(question);
                }
                Map<String, Object> questionsMap = new HashMap<String, Object>();
                questionsMap.put("question", questions);
                questionsMap.put("answered", studentQuestionList);
                dataMapList.put("questions", questionsMap);
                dataMap.put("answeredNum", studentQuestionList.size());
                answeredNum = studentQuestionList.size();
            } else {//学员不存在未完成的答卷，则直接生成试卷
                dataMapList = BuildPaperUtil.BuildTestPaper(test, studentId);
                list = TestpaperResult.dao.getTestpaperResult(studentId, test.getLong("id"), "myexamtest", 0, -1, null);
                if (list.size() > 0) {
                    testpaperResult = list.get(0);
                }
            }
        }
        if (answeredNum == 0) {
            dataMap.put("answeredNum", 0);
        }
        dataMap.put("limited_time", testpaperResult.getInt("limited_time"));
        dataMap.put("testpaper_id", testpaperResult.getLong("testpaper_id"));
        dataMap.put("questionAbout", dataMapList);
        finalMap.put("testPaper", dataMap);
        renderJson(JsonKit.mapToJson(finalMap, 39));
    }

    /**
     * 查看班级考试成绩0930
     */
    public void myExamScore(){
        Long myexamId = getParaToLong("myexamId");
        Long studentId = getParaToLong("studentId");
        Exam myExam = Exam.dao.getCourseExam(myexamId, "myexam");
        TestpaperResult testpaperResult = TestpaperResult.dao.findMaxScore(studentId, myExam.getLong("id"), "myexam");
        Map<String,Object> dataMap = new HashMap<String, Object>();
        dataMap.put("score",testpaperResult.getInt("score"));
        dataMap.put("usedTime",testpaperResult.getInt("used_time"));
        dataMap.put("testpaperId",testpaperResult.getLong("testpaper_id"));
        renderJson(JsonKit.mapToJson(dataMap,39));
    }

}
